package mybatisGenerator;


import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

import java.util.*;

/**
 * @description mybatisGenerator
 *
 * 参考：https://blog.csdn.net/zhangHP_123/article/details/126061630
 * 源码：https://gitee.com/zhp1221/java/tree/master/lab_02_mybatis_plus/generate
 *
 * @author: LI
 * @Date: 2023/6/27 16:38
 */
public class CreateCodeMain {

    public static void main(String[] args) {

        // 包名
        String packageName = "com.panasonic.server.modules.system";
        // 输出目录，一般指定到java目录
        String outputDir = "C:\\temp\\";
        // 输出目录 xml
        String outputDirXml = "C:\\temp\\" + packageName.replaceAll("\\.", "\\\\") + "\\mapper\\xml\\";
        // 表名数组
        List<String> tableNames = Arrays.asList(new String[]{"menu_tbl"});

        //创建一个代码生成器
        FastAutoGenerator.create(
                        "jdbc:postgresql://192.168.10.44:5432/energy_viewer_db?serverTimezone=UTC",
                        "postgres",
                        "postgres")
                //全局配置(GlobalConfig)
                .globalConfig(builder -> {
                    builder.author("LI") // 设置作者，可以写自己名字
                            //.enableSwagger() // 开启 swagger 模式，这个是接口文档生成器，如果开启的话，就还需要导入swagger依赖
                            .fileOverride() // 覆盖已生成文件
                            .dateType(DateType.TIME_PACK) //时间策略
                            .commentDate("yyyy-MM-dd") //注释日期
//                            .outputDir("C:\\IDEAWorkSpace\\work01\\lost_found\\src\\main\\java"); // 指定输出目录，一般指定到java目录
                            .outputDir(outputDir); // 指定输出目录，一般指定到java目录
                })
                //包配置(PackageConfig)
                .packageConfig(builder -> {
                    builder.parent(packageName) // 设置父包名
                            .moduleName("") // 设置父包模块名，这里一般不设置
//                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "C:\\IDEAWorkSpace\\work01\\lost_found\\src\\main\\resources\\com\\atguigu\\mapper")); // 设置mapperXml生成路径，这里是Mapper配置文件的路径，建议使用绝对路径
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, outputDirXml)); // 设置mapperXml生成路径，这里是Mapper配置文件的路径，建议使用绝对路径
                })
                //策略配置(StrategyConfig)
                .strategyConfig(builder -> {

                    // 添加表名
                    for (String tableName : tableNames) {
                        builder.addInclude(tableName);
                    }

                    builder
//                            .addInclude("menu_tbl") // 设置需要生成的表名
//                            .addInclude("tbl_found") // 设置需要生成的表名
//                            .addInclude("tbl_identify") // 设置需要生成的表名
//                            .addInclude("tbl_lost") // 设置需要生成的表名
//                            .addInclude("tbl_school") // 设置需要生成的表名
//                            .addInclude("tbl_status") // 设置需要生成的表名
//                            .addInclude("tbl_user") // 设置需要生成的表名
                            .addTablePrefix("tbl_"); // 设置过滤表前缀

                    builder.entityBuilder()
                            .enableTableFieldAnnotation()
                            .enableLombok();
                    builder.serviceBuilder()
                            .formatServiceFileName("%sService") //设置service的命名策略,没有这个配置的话，生成的service和serviceImpl类前面会有一个I，比如IUserService和IUserServiceImpl
                            .formatServiceImplFileName("%sServiceImpl"); //设置serviceImpl的命名策略
                    builder.controllerBuilder()
                            .enableRestStyle(); // 开启生成@RestController 控制器，不配置这个默认是Controller注解，RestController是返回Json字符串的，多用于前后端分离项目。
                    builder.mapperBuilder()
                            .enableMapperAnnotation();//开启 @Mapper 注解，也就是在dao接口上添加一个@Mapper注解，这个注解的作用是开启注解模式，就可以在接口的抽象方法上面直接使用@Select和@Insert和@Update和@Delete注解。
                })
                .injectionConfig(builder -> {
//                    // tag::custom file
//                    // 自定义vo，ro，qo等数据模型
//                    Map<String, String> customFile = new HashMap<>();
//                    customFile.put(CustomEnum.VO.getModelSuffix(), CustomEnum.VO.getPath());
//                    customFile.put(CustomEnum.RO.getModelSuffix(), CustomEnum.RO.getPath());
//                    customFile.put(CustomEnum.QO.getModelSuffix(), CustomEnum.QO.getPath());
//                    // 自定义MapStruct
//                    customFile.put(CustomEnum.CONVERTER.getModelSuffix(), CustomEnum.CONVERTER.getPath());
//                    // end::custom file

//                    builder.customFile(customFile); // 自定义模板

                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("r", "com.panasonic.server.modules.common.response.R");
                    builder.customMap(customMap);

                })

                // 模板配置(TemplateConfig)
//                .templateConfig(builder -> {
//                    // 设置模板路径
//                    builder.entity("/templates/entity.java.vm");
//                    builder.mapper("/templates/mapper.java.vm");
//                    builder.mapperXml("/templates/mapper.xml.vm");
//                    builder.mapperXml("/templates/controller.java.vm");
//                    builder.service("/templates/service.java.vm");
//                    builder.serviceImpl("/templates/serviceImpl.java.vm");
//                    builder.controller("/templates/controller.java.vm");
//                })
//                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .templateEngine(new VelocityTemplateEngine() {
                    @Override
                    public Map<String, Object> getObjectMap(ConfigBuilder config, TableInfo tableInfo) {
                        // 获取object map
                        Map<String, Object> objectMap = super.getObjectMap(config, tableInfo);
                        String entityName = tableInfo.getEntityName();
                        String entityPackage = (String) ((Map<String, Object>) objectMap.get("package")).get("Entity");
                        objectMap.put("entityVo", entityPackage + "." + entityName);
                        return objectMap;
                    }
                })
                .execute(); //执行以上配置
    }
}
